/*
 *  field_info.c
 *
 *  Copyright (C) 2011  Jason<linux8192@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <assert.h>
#include <stdio.h>
#include "debug.h"
#include "type.h"
#include "mem.h"
#include "big_endian_tool.h"
#include "constant_info.h"
#include "attribute_info.h"
#include "field_info.h"

static dump_each_field(field_info_t *field)
{
	printf("\taccess_flags = 0x%04x, name_index = 0x%04x, descriptor_index = 0x%04x, attributes_count = %d\n",
	       field->access_flags, field->name_index, field->descriptor_index, field->attributes_count);
}

void dump_fields_info(field_info_t **field_list, const int field_cnt)
{
	int	i;

	printf("dump fields info:\n");

	if (field_cnt == 0) {
		printf("\tno fields info\n");
		return;
	}

	for (i = 0; i < field_cnt; ++i) {
		printf("FIELD [%d]:\n", i);
		dump_each_field(field_list[i]);
	}
}

field_info_t **parse_fields_info(char *buff, const int field_cnt, const cp_info_t **cp_list, int *len)
{
	int		i;
	int		tmp;
	int		field_count;
	int		field_attr_cnt;
	char		*cur;
	field_info_t	**field_info;

	LOG_ENTER();
	//LOGV("field count = %d\n", field_cnt);

	assert(buff);

	field_info = mem_alloc(sizeof(field_info_t *) * field_cnt);

	for (i = 0, *len = 0; i < field_cnt; ++i) {
		field_attr_cnt = read_u2(buff + 6);
		field_info[i] = mem_alloc(sizeof(field_info_t) + sizeof(attr_t *) * field_attr_cnt);

		field_info[i]->access_flags = read_u2_and_move_cur(&buff);
		field_info[i]->name_index = read_u2_and_move_cur(&buff);
		field_info[i]->descriptor_index = read_u2_and_move_cur(&buff);
		field_info[i]->attributes_count = read_u2_and_move_cur(&buff);

		assert(field_attr_cnt == field_info[i]->attributes_count);

		LOGV("field_info[i]->attributes = 0x%08x, field_attr_len = %d\n",
		     field_info[i]->attributes, field_attr_cnt);

		tmp = parse_attribute_pool(buff, field_info[i]->attributes, field_attr_cnt, cp_list);
		buff += tmp;

		*len += 8;
		*len += tmp;
		*len += FIELD_INFO_SIZE_WITHOUT_ATTR_LIST;	
	}

	LOG_LEAVE();
	return field_info;
}
